<!DOCTYPE html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
div {
    width: 400px;
    height: 50px;
    margin-bottom: 5px;
}

#twocycleinfallback_a {
    --a: var(--b, red);
    --b: var(--not-defined, var(--a));
    background-color: orange;
    background-color: var(--a, green);
}

#twocycleinfallback_ra {
    --b: var(--a, red);
    --a: var(--not-defined, var(--b));
    background-color: orange;
    background-color: var(--b, green);
}

#twocycleinfallback_b {
    --c: var(--d, red);
    --d: var(--e, var(--c));
    --e: yellow;
    background-color: orange;
    background-color: var(--d, green);
}

#twocycleinfallback_rb {
    --d: var(--c, red);
    --c: var(--e, var(--d));
    --e: yellow;
    background-color: orange;
    background-color: var(--c, green);
}

#twocycleinchain_a {
  --e: var(--f) red;
  --f: var(--not-defined) var(--e);
  background-color: orange;
  background-color: var(--f, green);
}

#twocycleinchain_ra {
  --f: var(--e) red;
  --e: var(--not-defined) var(--f);
  background-color: orange;
  background-color: var(--e, green);
}

#twocycleinchain_b {
  --g: var(--h) red;
  --h: var(--i) var(--g);
  --i: ;
  background-color: orange;
  background-color: var(--h, green);
}

#twocycleinchain_rb {
  --h: var(--g) red;
  --g: var(--i) var(--h);
  --i: ;
  background-color: orange;
  background-color: var(--g, green);
}

#secondarycycle_chain {
  --j: var(--k, pink);
  --k: var(--j) var(--l);
  --l: var(--k, red);
  background-color: orange;
  background-color: var(--j, var(--l, green));
}

#secondarycycle_chain_r {
  --k: var(--j, pink);
  --j: var(--k) var(--l);
  --l: var(--j, red);
  background-color: orange;
  background-color: var(--k, var(--l, green));
}

#secondarycycle_fallback {
  --m: var(--n, pink);
  --n: var(--m, var(--o));
  --o: var(--n, red);
  background-color: orange;
  background-color: var(--m, var(--o, green));
}

#secondarycycle_fallback_r {
  --n: var(--m, pink);
  --m: var(--n, var(--o));
  --o: var(--m, red);
  background-color: orange;
  background-color: var(--n, var(--o, green));
}

#twocycle_with_separate_fallback {
  --a: var(--b) var(--c, red);
  --b: var(--a) var(--c, red);
  background-color: orange;
  background-color: var(--a, green);
}

#linked_cycles_a {
  --a: var(--b) var(--c, red);
  --b: var(--a) var(--c, red);
  --c: var(--a);
  background-color: orange;
  background-color: var(--a, green);
}

#linked_cycles_b {
  --a: var(--b) var(--c, var(--d));
  --b: var(--a) var(--c, red);
  --d: var(--a);
  background-color: orange;
  background-color: var(--a, var(--d, green));
}

#fallback_self_reference_a {
  --a: red;
  --b: var(--a, var(--b));
  --c: var(--b, green);
  background-color: orange;
  background-color: var(--c, red);
}

#fallback_self_reference_b {
  --b: red;
  --c: var(--b, var(--c));
  --a: var(--c, green);
  background-color: orange;
  background-color: var(--a, red);
}

#fallback_self_reference_c {
  --c: red;
  --a: var(--c, var(--a));
  --b: var(--a, green);
  background-color: orange;
  background-color: var(--b, red);
}

</style>

<div id=twocycleinfallback_a></div>
<div id=twocycleinfallback_ra></div>
<div id=twocycleinfallback_b></div>
<div id=twocycleinfallback_rb></div>
<div id=twocycleinchain_a></div>
<div id=twocycleinchain_ra></div>
<div id=twocycleinchain_b></div>
<div id=twocycleinchain_rb></div>
<div id=secondarycycle_chain></div>
<div id=secondarycycle_chain_r></div>
<div id=secondarycycle_fallback></div>
<div id=secondarycycle_fallback_r></div>
<div id=twocycle_with_separate_fallback></div>
<div id=linked_cycles_a></div>
<div id=linked_cycles_b></div>
<div id=fallback_self_reference_a></div>
<div id=fallback_self_reference_b></div>
<div id=fallback_self_reference_c></div>

<script>
test(function() {
  assert_equals(getComputedStyle(twocycleinfallback_a).backgroundColor, 'rgb(0, 128, 0)');
  assert_equals(getComputedStyle(twocycleinfallback_ra).backgroundColor, 'rgb(0, 128, 0)');
}, 'A cycle is still invalid if it uses fallbacks (fallback forced)');

test(function() {
  assert_equals(getComputedStyle(twocycleinfallback_b).backgroundColor, 'rgb(0, 128, 0)');
  assert_equals(getComputedStyle(twocycleinfallback_rb).backgroundColor, 'rgb(0, 128, 0)');
}, 'A cycle is still invalid if it uses fallbacks (fallback not taken)');

test(function() {
  assert_equals(getComputedStyle(twocycleinchain_a).backgroundColor, 'rgb(0, 128, 0)');
  assert_equals(getComputedStyle(twocycleinchain_ra).backgroundColor, 'rgb(0, 128, 0)');
}, 'A cycle is still invalid if it uses chains (A)');

test(function() {
  assert_equals(getComputedStyle(twocycleinchain_b).backgroundColor, 'rgb(0, 128, 0)');
  assert_equals(getComputedStyle(twocycleinchain_rb).backgroundColor, 'rgb(0, 128, 0)');
}, 'A cycle is still invalid if it uses chains (B)');

test(function() {
  assert_equals(getComputedStyle(secondarycycle_chain).backgroundColor, 'rgb(0, 128, 0)');
  assert_equals(getComputedStyle(secondarycycle_chain_r).backgroundColor, 'rgb(0, 128, 0)');
}, 'Secondary cycles need to be detected too (secondary cycle in chain)');

test(function() {
  assert_equals(getComputedStyle(secondarycycle_fallback).backgroundColor, 'rgb(0, 128, 0)');
  assert_equals(getComputedStyle(secondarycycle_fallback_r).backgroundColor, 'rgb(0, 128, 0)');
}, 'Secondary cycles need to be detected too (secondary cycle in fallback)');

test(function() {
  assert_equals(getComputedStyle(twocycle_with_separate_fallback).backgroundColor, 'rgb(0, 128, 0)');
}, 'A cycle is not affected by other variable references with fallbacks');

test(function() {
  assert_equals(getComputedStyle(linked_cycles_a).backgroundColor, 'rgb(0, 128, 0)');
  assert_equals(getComputedStyle(linked_cycles_b).backgroundColor, 'rgb(0, 128, 0)');
}, 'Cycles which are linked are invalid');

test(function() {
  assert_equals(getComputedStyle(fallback_self_reference_a).backgroundColor, 'rgb(0, 128, 0)');
  assert_equals(getComputedStyle(fallback_self_reference_b).backgroundColor, 'rgb(0, 128, 0)');
  assert_equals(getComputedStyle(fallback_self_reference_c).backgroundColor, 'rgb(0, 128, 0)');
}, 'A self-reference in a fallback is invalid');
</script>
